/** 
 * 视频文件相关处理
 * 
 * compressVideo 保证画质的前提下压缩文件大小
 * mixingVideoAudio 视频音频混流
 * 
 */

import { getVideoDurationInSeconds } from 'get-video-duration'
import { spawn, exec } from 'child_process'

/** 
 * 压缩文件
 */
export async function compressVideo(sourceFilePath: string, outFilePath: string, callback: (params: {
  /** 进度百分比 */
  progress: number
}) => void) {

  // 获取视频信息
  let duration = await getVideoDurationInSeconds(sourceFilePath).then(duration => duration) * 1000

  // 压缩视频
  await new Promise<void>((resolve, reject) => {

    let child = spawn(`ffmpeg`, [
      '-i', sourceFilePath, '-c:v', 'libx264', '-x265-params', 'crf=18:preset=placebo', outFilePath,   // 最小
      // '-i', sourceFilePath, '-c:v', 'libx264', '-q:v', '20', '-b:v', '2M', outFilePath,             // 中等
      // '-i', sourceFilePath, '-c:v', 'libx264', '-x264-params', 'crf=18:preset=placebo', outFilePath,// 最大
    ])
    child.on('close', () => {
      callback({ progress: 100 })
      resolve()
    })
    child.on('error', console.error)
    child.stdout.on('data', (data) => {
      console.log(data.toString())
    })
    child.stderr.on('data', (data) => {
      let str = data.toString()
      // console.log(str)
      // frame= 4138 fps=125 q=28.0 size=   53760kB time=00:02:55.63 bitrate=2507.5kbits/s speed=5.31x
      let startIndex_frame = str.indexOf('frame=')
      let startIndex_fps = str.indexOf('fps=')
      let startIndex_q = str.indexOf('q=')
      let startIndex_size = str.indexOf('size=')
      let startIndex_time = str.indexOf('time=')
      let startIndex_bitrate = str.indexOf('bitrate=')
      let startIndex_speed = str.indexOf('speed=')

      let frame = str.substring(startIndex_frame, startIndex_fps).replace(/[ \r]/g, '').split('=')[1]
      let fps = str.substring(startIndex_fps, startIndex_q).replace(/[ \r]/g, '').split('=')[1]
      let q = str.substring(startIndex_q, startIndex_size).replace(/[ \r]/g, '').split('=')[1]
      let size = str.substring(startIndex_size, startIndex_time).replace(/[ \r]/g, '').split('=')[1]
      let time = str.substring(startIndex_time, startIndex_bitrate).replace(/[ \r]/g, '').split('=')[1]
      let bitrate = str.substring(startIndex_bitrate, startIndex_speed).replace(/[ \r]/g, '').split('=')[1]
      let speed = str.substring(startIndex_speed).replace(/[ \r]/g, '').split('=')[1]

      if (time && callback) {
        // console.log({ frame, fps, q, size, time, bitrate, speed, }, '\n')
        let progress = Number((str2hm(time) / duration * 100).toFixed(2))
        // console.log(time, duration, `${progress}%`)
        // console.log(outFilePath, `${progress}%`)

        callback({ progress })

      }

    })

  })

}

/** 
 * 合成音视频
 */
export async function mixingVideoAudio(options: {
  sourceVideoPath: string,
  sourceAudioPath: string,
  outFilePath: string
}, callback: (params: {
  /** 进度百分比 */
  progress: number
}) => void) {

  // 获取视频信息
  let duration = await getVideoDurationInSeconds(options.sourceVideoPath).then(duration => duration) * 1000

  // 压缩视频
  await new Promise<void>((resolve, reject) => {

    // exec(`ffmpeg -i ${options.sourceVideoPath} -i ${options.sourceAudioPath} -c:v copy -c:a copy -f mp4 ${options.outFilePath}`, (error) => {
    //   if (error) {
    //     console.log(error)
    //   }
    // })

    // // exec(`ffmpeg -loglevel quiet -i ${options.sourceVideoPath} -i ${options.sourceAudioPath} -c copy -y ${options.outFilePath}`, (error) => {
    // //   if (error) {
    // //     console.log(error)
    // //   }
    // // })

    let child = spawn(`ffmpeg`, [
      '-i', options.sourceVideoPath, '-i', options.sourceAudioPath, '-c:v', 'copy', '-c:a', 'copy', '-f', 'mp4', options.outFilePath,
    ])
    child.on('close', () => {
      callback({ progress: 100 })
      resolve()
    })
    child.on('error', console.error)
    child.stdout.on('data', (data) => {
      console.log(data.toString())
    })
    child.stderr.on('data', (data) => {
      let str = data.toString()
      // console.log(str)
      // frame= 4138 fps=125 q=28.0 size=   53760kB time=00:02:55.63 bitrate=2507.5kbits/s speed=5.31x
      let startIndex_frame = str.indexOf('frame=')
      let startIndex_fps = str.indexOf('fps=')
      let startIndex_q = str.indexOf('q=')
      let startIndex_size = str.indexOf('size=')
      let startIndex_time = str.indexOf('time=')
      let startIndex_bitrate = str.indexOf('bitrate=')
      let startIndex_speed = str.indexOf('speed=')

      let frame = str.substring(startIndex_frame, startIndex_fps).replace(/[ \r]/g, '').split('=')[1]
      let fps = str.substring(startIndex_fps, startIndex_q).replace(/[ \r]/g, '').split('=')[1]
      let q = str.substring(startIndex_q, startIndex_size).replace(/[ \r]/g, '').split('=')[1]
      let size = str.substring(startIndex_size, startIndex_time).replace(/[ \r]/g, '').split('=')[1]
      let time = str.substring(startIndex_time, startIndex_bitrate).replace(/[ \r]/g, '').split('=')[1]
      let bitrate = str.substring(startIndex_bitrate, startIndex_speed).replace(/[ \r]/g, '').split('=')[1]
      let speed = str.substring(startIndex_speed).replace(/[ \r]/g, '').split('=')[1]

      if (time && callback) {
        // console.log({ frame, fps, q, size, time, bitrate, speed, }, '\n')
        let progress = Number((str2hm(time) / duration * 100).toFixed(2))
        // console.log(time, duration, `${progress}%`)
        // console.log(outFilePath, `${progress}%`)

        callback({ progress: time })

      }

    })

  })

}

/** 
 * 时间转时分秒
 */
function str2hm(str: string) {
  let hm = str.split('.')[1] || 0
  hm = Number(hm)
  let shifenmiao = str.split('.')[0] || ''
  let arr = shifenmiao.split(':').map(item => Number(item))
  let hour = 0
  let minute = 0
  let second = 0
  if (arr.length === 3) {
    [hour, minute, second] = arr
  } else if (arr.length === 2) {
    [minute, second,] = arr
  } else if (arr.length === 1) {
    [second] = arr
  }
  return (hour * 60 * 60 * 1000) + (minute * 60 * 1000) + (second * 1000) + hm
}